home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 11 / CU Amiga Magazine's Super CD-ROM 11 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-06].iso / cucd / graphics / mpimage / si / p2c.asm < prev    next >
Assembly Source File  |  1995-07-16  |  8KB  |  403 lines

  1. ;------------------------------------------------------------------------------
  2. ;
  3. ; 100% systemfriendly PlanarToChunky converter for use with intuition
  4. ; screens in applications/games/whatever.
  5. ;
  6. ; Coded in 1994 by Morten Eriksen.
  7. ; Reach me through email: mortene@stud.unit.no.
  8. ;
  9. ; Use and modify as you like - give credit where appropriate.
  10. ;
  11. ; Timings on my A1200 with 68EC020 and 32-bit fastram:
  12. ;
  13. ;  Testcase    Dimensions       This routine             C='s ReadPixelArray8
  14. ;
  15. ;    1    320x256x5 -    10 frames (0.20 seconds)    41 frames
  16. ;    2    320x256x8 -    16 frames (0.32 seconds)    51 frames
  17. ;    3    640x512x4 -    34 frames (0.68 seconds)    158 frames
  18. ;    4     1024x1024x1 -    35 frames (0.70 seconds)    312 frames
  19. ;    5    752x578x8 -    89 frames (1.78 seconds)    312 frames
  20. ;
  21. ; Please suggest speed-ups in the code if you see any (by changing the
  22. ; algorithm, using other instructions with less executiontime, better
  23. ; pipelining, etc etc). The 'convert32pixels' is of course the bottleneck,
  24. ; as this subroutine accounts for almost all processing done in the
  25. ; converter.
  26. ;
  27. ;------------------------------------------------------------------------------
  28.     xdef    _PlanarToChunkyAsm
  29. ;------------------------------------------------------------------------------
  30. ; This routine takes a buffer of chunkybytes and fills it with converted
  31. ; planar datas from the source BitMap.
  32. ;
  33. ; As a replacement for C='s ReadPixelArray8 routine, this one is more than
  34. ; three times as fast (in worst case) and works directly on bitmaps (instead
  35. ; of RastPorts). All cases handled (any width and height > 0, no alignment
  36. ; restrictions). Works on OCS/ECS/AGA, all Kickstarts and any MC680x0 CPU.
  37. ; The downside is that it does not do clipping and does not work with
  38. ; interleaved bitmaps (support for interleaved bitmaps should be piece of
  39. ; cake to implement, though).
  40. ;------------------------------------------------------------------------------
  41. ;
  42. ; C interface:
  43. ;
  44. ; extern void __asm PlanarToChunkyAsm(register __a0 struct p2cStruct *);
  45. ;
  46. ; struct p2cStruct
  47. ; {
  48. ;  struct BitMap *bmap;
  49. ;  UWORD startX, startY, width, height;
  50. ;  UBYTE *chunkybuffer;
  51. ; } p2c;
  52. ;
  53. ; p2c.bmap = mybitmap;
  54. ; p2c.startX = x0;
  55. ; p2c.startY = y0;
  56. ; p2c.width = x1 - x0 + 1;
  57. ; p2c.height = y1 - y0 + 1;
  58. ; p2c.chunkybuffer = chunkybytes;
  59. ;
  60. ; SyncSBitMap(mywindow->RPort->Layer);
  61. ; PlanarToChunkyAsm(&p2c);
  62. ;------------------------------------------------------------------------------
  63. ;
  64. ; Assembler interface:
  65. ;
  66. ; In:     a0 - p2c struct.
  67. ; Out:    Nothing.
  68. ;------------------------------------------------------------------------------
  69.  
  70. ; ** BitMap struct **
  71. BytesPerRow    EQU    0    ; UWORD
  72. Rows        EQU    2    ; UWORD
  73. Flags        EQU    4    ; UBYTE
  74. Depth        EQU    5    ; UBYTE
  75. Pad        EQU    6    ; UWORD
  76. Planes        EQU    8    ; PLANEPTRs [8]
  77.  
  78. ; ** p2c struct **
  79.  
  80. bmap        EQU    0    ; struct BitMap *
  81. startX        EQU    4    ; UWORD
  82. startY        EQU    6    ; UWORD
  83. width        EQU    8    ; UWORD
  84. height        EQU    10    ; UWORD
  85. chunkybuffer    EQU    12    ; UBYTE *
  86.  
  87. AttnFlags    EQU    296
  88. ;------------------------------------------------------------------------------
  89.     Section    code,CODE
  90.     
  91. _PlanarToChunkyAsm:
  92.     movem.l    d2-d7/a2-a6,-(sp)
  93.  
  94.     tst.b    madetable    * need only make bitspreadtable on first call
  95.     bne.s    table_made
  96.     bsr.w    make_table
  97.  
  98.     move.l    4.w,a1        * and ditto for 68020 check
  99.     clr.b    chk68000
  100.     move.w    AttnFlags(a1),d0
  101.     andi.b    #%1110,d0
  102.     tst.b    d0
  103.     bne.s    atleast68020
  104.     move.b    #1,chk68000
  105. atleast68020
  106. table_made
  107.  
  108.     move.l    bmap(a0),a1
  109.     move.l    chunkybuffer(a0),a3
  110.     lea    p2c,a4
  111.  
  112.     moveq    #0,d1
  113.     move.w    startX(a0),d0
  114.     andi.w    #%111,d0
  115.     tst.w    d0
  116.     beq.s    noleftpix
  117.     moveq    #8,d1
  118.     sub.w    d0,d1
  119. noleftpix
  120.     move.w    d1,leftpix
  121.  
  122.     move.w    width(a0),d0
  123.     move.w    d0,Width
  124. hit    cmp.w    d1,d0
  125.     bhs.s    notinsidebyte
  126.     move.b    #1,insidebyte
  127.     moveq    #0,d1
  128.     bra.s    isinside
  129.  
  130. notinsidebyte
  131.     clr.b    insidebyte
  132.     move.w    Width,d0
  133.     sub.w    leftpix,d0
  134.     move.w    d0,d1
  135.     lsr.w    #5,d0
  136.     lsl.w    #5,d0
  137.     sub.w    d0,d1
  138. isinside
  139.     move.w    d1,rightpix
  140.  
  141.     * find initial offset in bytes into bitmap given by (startX, startY)
  142.     moveq    #0,d0
  143.     move.w    startX(a0),d0
  144.     lsr.w    #3,d0
  145.     move.w    startY(a0),d1
  146.     tst.w    d1
  147.     beq.s    line0
  148.     moveq    #0,d2
  149.     move.w    BytesPerRow(a1),d2
  150.     subq    #1,d1
  151. makeoffset
  152.     add.l    d2,d0
  153.     dbra    d1,makeoffset
  154. line0    move.l    d0,a2
  155.  
  156.     tst.w    leftpix
  157.     beq.s    nol1
  158.     subq    #3,a2
  159.  
  160. nol1    move.w    Width,d0
  161.     sub.w    rightpix,d0
  162.     move.w    BytesPerRow(a1),d1
  163.     lsr.w    #3,d0
  164.     sub.w    d0,d1
  165.     move.w    d1,Modulo
  166.  
  167.     tst.b    insidebyte
  168.     bne.s    nol2
  169.     tst.w    leftpix
  170.     beq.s    nol2
  171.     subq    #4,Modulo
  172. nol2
  173.  
  174.     move.w    height(a0),Height
  175.  
  176.     ; a0 - c2p struct, a1 - bmap,
  177.     ; a2 - offset from Planes pointer, a3 - chunkybuffer
  178.     ; a4 - bitspread table
  179.  
  180.     move.l    a1,a6
  181.     add.w    #Planes,a6
  182.     moveq    #0,d0
  183.     move.b    Depth(a1),d0
  184.     move.w    d0,depth
  185.     lsl.w    #2,d0
  186.     add.l    d0,a6
  187.     move.l    a6,lastplaneptr
  188.  
  189. convertline
  190.     tst.b    insidebyte
  191.     beq.s    notinsidesinglebyte
  192.     bsr.w    convert32pixels
  193.     lea    buffer+32,a5
  194.     movem.l    d0-d7,-(a5)
  195.     moveq    #32,d0
  196.     sub.w    leftpix,d0
  197.     add.l    d0,a5
  198.     move.w    Width,d0
  199.     subq    #1,d0
  200. singleinsert
  201.     move.b    (a5)+,(a3)+
  202.     dbra    d0,singleinsert
  203.     bra.w    linedone
  204.  
  205. notinsidesinglebyte
  206.     tst.w    leftpix
  207.     beq.s    noleftpixels
  208.  
  209.     tst.w    Width
  210.     beq.w    linedone
  211.  
  212.     bsr.w    convert32pixels
  213.     lea    buffer+32,a5
  214.     movem.l    d0-d7,-(a5)
  215.     moveq    #32,d0
  216.     sub.w    leftpix,d0
  217.     add.l    d0,a5
  218.     move.w    leftpix,d0
  219.     move.w    d0,d1
  220.     subq    #1,d0
  221. leftinsert
  222.     move.b    (a5)+,(a3)+
  223.     dbra    d0,leftinsert
  224.     sub.w    d1,Width
  225.     addq    #4,a2
  226.     
  227. noleftpixels
  228.     cmp.w    #32,Width
  229.     blo.s    trailbits
  230.  
  231.     bsr.w    convert32pixels
  232.  
  233.     tst.b    chk68000
  234.     beq.b    flushall
  235.     move.w    a3,dummy
  236.     andi.w    #%1,dummy
  237.     tst.w    dummy
  238.     beq.b    flushall
  239.  
  240.     lea    buffer+32,a5
  241.     movem.l    d0-d7,-(a5)
  242.     moveq    #(32/8)-1,d0
  243. mloop    move.b    (a5)+,(a3)+
  244.     move.b    (a5)+,(a3)+
  245.     move.b    (a5)+,(a3)+
  246.     move.b    (a5)+,(a3)+
  247.     move.b    (a5)+,(a3)+
  248.     move.b    (a5)+,(a3)+
  249.     move.b    (a5)+,(a3)+
  250.     move.b    (a5)+,(a3)+
  251.     dbra    d0,mloop
  252.     bra.s    nolongflush
  253.  
  254. flushall
  255.     add.w    #32,a3
  256.     movem.l    d0-d7,-(a3)
  257.     add.w    #32,a3
  258.  
  259. nolongflush
  260.     sub.w    #32,Width
  261.     addq    #4,a2
  262.     bra.b    noleftpixels
  263.  
  264. trailbits
  265.     tst.w    Width
  266.     beq.s    linedone
  267.  
  268.     bsr.b    convert32pixels
  269.     lea    buffer+32,a5
  270.     movem.l    d0-d7,-(a5)
  271.     move.w    rightpix,d0
  272.     subq    #1,d0
  273. rightinsert
  274.     move.b    (a5)+,(a3)+
  275.     dbra    d0,rightinsert
  276.  
  277. linedone
  278.     move.w    width(a0),Width
  279.     add.w    Modulo,a2
  280.     subq    #1,Height
  281.     tst.w    Height
  282.     bne.w    convertline
  283.  
  284.     movem.l    (sp)+,d2-d7/a2-a6
  285.     rts
  286. ;------------------------------------------------------------------------------
  287. convert32pixels:
  288.     move.l    a3,-(sp)
  289.     move.w    depth,a3
  290.     move.l    lastplaneptr,a6
  291.     
  292.     move.l    -(a6),a5
  293.     add.l    a2,a5
  294.     clr.w    d7
  295.     move.b    (a5)+,d7
  296.     lsl.w    #3,d7
  297.     movem.l    0(a4,d7.w),d0/d1
  298.     clr.w    d7
  299.     move.b    (a5)+,d7
  300.     lsl.w    #3,d7
  301.     movem.l    0(a4,d7.w),d2/d3
  302.     clr.w    d7
  303.     move.b    (a5)+,d7
  304.     lsl.w    #3,d7
  305.     movem.l    0(a4,d7.w),d4/d5
  306.     clr.w    d7
  307.     move.b    (a5)+,d7
  308.     lsl.w    #3,d7
  309.     movem.l    0(a4,d7.w),d6/d7
  310.  
  311. convert32pixelsloop
  312.     subq    #1,a3
  313.     cmp.w    #0,a3
  314.     beq.s    done
  315.  
  316.     move.l    -(a6),a5
  317.     add.l    a2,a5
  318.     move.w    d7,-(sp)
  319.     clr.w    d7
  320.     move.b    (a5)+,d7
  321.     lsl.w    #3,d7
  322.     add.l    d0,d0
  323.     or.l    0(a4,d7.w),d0
  324.     add.l    d1,d1
  325.     or.l    4(a4,d7.w),d1
  326.     clr.w    d7
  327.     move.b    (a5)+,d7
  328.     lsl.w    #3,d7
  329.     add.l    d2,d2
  330.     or.l    0(a4,d7.w),d2
  331.     add.l    d3,d3
  332.     or.l    4(a4,d7.w),d3
  333.     clr.w    d7
  334.     move.b    (a5)+,d7
  335.     lsl.w    #3,d7
  336.     add.l    d4,d4
  337.     or.l    0(a4,d7.w),d4
  338.     add.l    d5,d5
  339.     or.l    4(a4,d7.w),d5
  340.     move.w    (sp)+,d7
  341.     move.w    d5,-(sp)
  342.     clr.w    d5
  343.     move.b    (a5)+,d5
  344.     lsl.w    #3,d5
  345.     add.l    d6,d6
  346.     or.l    0(a4,d5.w),d6
  347.     add.l    d7,d7
  348.     or.l    4(a4,d5.w),d7
  349.     move.w    (sp)+,d5
  350.     bra.s    convert32pixelsloop
  351.  
  352. done    move.l    (sp)+,a3
  353.     rts
  354. ;------------------------------------------------------------------------------
  355. * makes the bitspread table *
  356. * Do not destroy a0! *
  357. make_table:
  358.     lea    p2c,a1
  359.     moveq    #0,d0
  360. more_table
  361.     move.b    d0,d1
  362.  
  363.     moveq    #8-1,d2
  364. byteloop
  365.     btst    #7,d1
  366.     beq.s    zero
  367.     move.b    #1,(a1)+
  368.     bra.s    one
  369. zero    clr.b    (a1)+
  370. one    lsl.b    #1,d1
  371.     dbra    d2,byteloop
  372.  
  373.     addq    #1,d0
  374.     cmp.w    #256,d0
  375.     beq.s    table_done
  376.     bra.s    more_table
  377. table_done
  378.     move.b    #1,madetable    
  379.     rts
  380. ;------------------------------------------------------------------------------
  381.     Section    variables,DATA
  382.  
  383. lastplaneptr    dc.l    0
  384. Width        dc.w    0
  385. Height        dc.w    0
  386. depth        dc.w    0
  387. Modulo        dc.w    0
  388. dummy        dc.w    0
  389. leftpix        dc.w    0
  390. rightpix    dc.w    0
  391. insidebyte    dc.b    0
  392. madetable    dc.b    0
  393. chk68000    dc.b    0
  394. ;------------------------------------------------------------------------------
  395.     Section    tables,BSS    
  396.  
  397.     cnop    0,8
  398. * bitspread table *
  399. p2c    ds.b    256*8
  400. buffer    ds.b    32
  401. ;------------------------------------------------------------------------------
  402.     END
  403.